Skip to content

RMNRemote: curse admin management + legacy rmn removal [CCIP-10871]#1991

Open
asoliman92 wants to merge 18 commits intomainfrom
asoliman/rmn-curse-admins
Open

RMNRemote: curse admin management + legacy rmn removal [CCIP-10871]#1991
asoliman92 wants to merge 18 commits intomainfrom
asoliman/rmn-curse-admins

Conversation

@asoliman92
Copy link
Copy Markdown
Contributor

@asoliman92 asoliman92 commented Apr 20, 2026

  • RMNRemote: curse admin management
  • Removed all legacy RMN functions
  • Renaming RMNRemote to RMN across the codebase

@@ -22,7 +22,7 @@ var ContractType cldf_deployment.ContractType = "FeeQuoter"
var Version = semver.MustParse("1.6.0")
var TypeAndVersion = cldf_deployment.NewTypeAndVersion(ContractType, *Version)

const FeeQuoterABI = `[{"type":"constructor","inputs":[{"name":"staticConfig","type":"tuple","internalType":"struct FeeQuoter.StaticConfig","components":[{"name":"maxFeeJuelsPerMsg","type":"uint96","internalType":"uint96"},{"name":"linkToken","type":"address","internalType":"address"},{"name":"tokenPriceStalenessThreshold","type":"uint32","internalType":"uint32"}]},{"name":"priceUpdaters","type":"address[]","internalType":"address[]"},{"name":"feeTokens","type":"address[]","internalType":"address[]"},{"name":"tokenPriceFeeds","type":"tuple[]","internalType":"struct FeeQuoter.TokenPriceFeedUpdate[]","components":[{"name":"sourceToken","type":"address","internalType":"address"},{"name":"feedConfig","type":"tuple","internalType":"struct FeeQuoter.TokenPriceFeedConfig","components":[{"name":"dataFeedAddress","type":"address","internalType":"address"},{"name":"tokenDecimals","type":"uint8","internalType":"uint8"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}]},{"name":"tokenTransferFeeConfigArgs","type":"tuple[]","internalType":"struct FeeQuoter.TokenTransferFeeConfigArgs[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"tokenTransferFeeConfigs","type":"tuple[]","internalType":"struct FeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenTransferFeeConfig","type":"tuple","internalType":"struct FeeQuoter.TokenTransferFeeConfig","components":[{"name":"minFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"maxFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"deciBps","type":"uint16","internalType":"uint16"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destBytesOverhead","type":"uint32","internalType":"uint32"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}]}]},{"name":"premiumMultiplierWeiPerEthArgs","type":"tuple[]","internalType":"struct FeeQuoter.PremiumMultiplierWeiPerEthArgs[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"premiumMultiplierWeiPerEth","type":"uint64","internalType":"uint64"}]},{"name":"destChainConfigArgs","type":"tuple[]","internalType":"struct FeeQuoter.DestChainConfigArgs[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"destChainConfig","type":"tuple","internalType":"struct FeeQuoter.DestChainConfig","components":[{"name":"isEnabled","type":"bool","internalType":"bool"},{"name":"maxNumberOfTokensPerMsg","type":"uint16","internalType":"uint16"},{"name":"maxDataBytes","type":"uint32","internalType":"uint32"},{"name":"maxPerMsgGasLimit","type":"uint32","internalType":"uint32"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destGasPerPayloadByteBase","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteHigh","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteThreshold","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityOverheadGas","type":"uint32","internalType":"uint32"},{"name":"destGasPerDataAvailabilityByte","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityMultiplierBps","type":"uint16","internalType":"uint16"},{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"},{"name":"enforceOutOfOrder","type":"bool","internalType":"bool"},{"name":"defaultTokenFeeUSDCents","type":"uint16","internalType":"uint16"},{"name":"defaultTokenDestGasOverhead","type":"uint32","internalType":"uint32"},{"name":"defaultTxGasLimit","type":"uint32","internalType":"uint32"},{"name":"gasMultiplierWeiPerEth","type":"uint64","internalType":"uint64"},{"name":"gasPriceStalenessThreshold","type":"uint32","internalType":"uint32"},{"name":"networkFeeUSDCents","type":"uint32","internalType":"uint32"}]}]}],"stateMutability":"nonpayable"},{"type":"function","name":"FEE_BASE_DECIMALS","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"KEYSTONE_PRICE_DECIMALS","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"acceptOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"applyAuthorizedCallerUpdates","inputs":[{"name":"authorizedCallerArgs","type":"tuple","internalType":"struct AuthorizedCallers.AuthorizedCallerArgs","components":[{"name":"addedCallers","type":"address[]","internalType":"address[]"},{"name":"removedCallers","type":"address[]","internalType":"address[]"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"applyDestChainConfigUpdates","inputs":[{"name":"destChainConfigArgs","type":"tuple[]","internalType":"struct FeeQuoter.DestChainConfigArgs[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"destChainConfig","type":"tuple","internalType":"struct FeeQuoter.DestChainConfig","components":[{"name":"isEnabled","type":"bool","internalType":"bool"},{"name":"maxNumberOfTokensPerMsg","type":"uint16","internalType":"uint16"},{"name":"maxDataBytes","type":"uint32","internalType":"uint32"},{"name":"maxPerMsgGasLimit","type":"uint32","internalType":"uint32"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destGasPerPayloadByteBase","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteHigh","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteThreshold","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityOverheadGas","type":"uint32","internalType":"uint32"},{"name":"destGasPerDataAvailabilityByte","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityMultiplierBps","type":"uint16","internalType":"uint16"},{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"},{"name":"enforceOutOfOrder","type":"bool","internalType":"bool"},{"name":"defaultTokenFeeUSDCents","type":"uint16","internalType":"uint16"},{"name":"defaultTokenDestGasOverhead","type":"uint32","internalType":"uint32"},{"name":"defaultTxGasLimit","type":"uint32","internalType":"uint32"},{"name":"gasMultiplierWeiPerEth","type":"uint64","internalType":"uint64"},{"name":"gasPriceStalenessThreshold","type":"uint32","internalType":"uint32"},{"name":"networkFeeUSDCents","type":"uint32","internalType":"uint32"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"applyFeeTokensUpdates","inputs":[{"name":"feeTokensToRemove","type":"address[]","internalType":"address[]"},{"name":"feeTokensToAdd","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"applyPremiumMultiplierWeiPerEthUpdates","inputs":[{"name":"premiumMultiplierWeiPerEthArgs","type":"tuple[]","internalType":"struct FeeQuoter.PremiumMultiplierWeiPerEthArgs[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"premiumMultiplierWeiPerEth","type":"uint64","internalType":"uint64"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"applyTokenTransferFeeConfigUpdates","inputs":[{"name":"tokenTransferFeeConfigArgs","type":"tuple[]","internalType":"struct FeeQuoter.TokenTransferFeeConfigArgs[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"tokenTransferFeeConfigs","type":"tuple[]","internalType":"struct FeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenTransferFeeConfig","type":"tuple","internalType":"struct FeeQuoter.TokenTransferFeeConfig","components":[{"name":"minFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"maxFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"deciBps","type":"uint16","internalType":"uint16"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destBytesOverhead","type":"uint32","internalType":"uint32"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}]}]},{"name":"tokensToUseDefaultFeeConfigs","type":"tuple[]","internalType":"struct FeeQuoter.TokenTransferFeeConfigRemoveArgs[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"token","type":"address","internalType":"address"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"convertTokenAmount","inputs":[{"name":"fromToken","type":"address","internalType":"address"},{"name":"fromTokenAmount","type":"uint256","internalType":"uint256"},{"name":"toToken","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getAllAuthorizedCallers","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"type":"function","name":"getDestChainConfig","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"","type":"tuple","internalType":"struct FeeQuoter.DestChainConfig","components":[{"name":"isEnabled","type":"bool","internalType":"bool"},{"name":"maxNumberOfTokensPerMsg","type":"uint16","internalType":"uint16"},{"name":"maxDataBytes","type":"uint32","internalType":"uint32"},{"name":"maxPerMsgGasLimit","type":"uint32","internalType":"uint32"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destGasPerPayloadByteBase","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteHigh","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteThreshold","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityOverheadGas","type":"uint32","internalType":"uint32"},{"name":"destGasPerDataAvailabilityByte","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityMultiplierBps","type":"uint16","internalType":"uint16"},{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"},{"name":"enforceOutOfOrder","type":"bool","internalType":"bool"},{"name":"defaultTokenFeeUSDCents","type":"uint16","internalType":"uint16"},{"name":"defaultTokenDestGasOverhead","type":"uint32","internalType":"uint32"},{"name":"defaultTxGasLimit","type":"uint32","internalType":"uint32"},{"name":"gasMultiplierWeiPerEth","type":"uint64","internalType":"uint64"},{"name":"gasPriceStalenessThreshold","type":"uint32","internalType":"uint32"},{"name":"networkFeeUSDCents","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"getDestinationChainGasPrice","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"","type":"tuple","internalType":"struct Internal.TimestampedPackedUint224","components":[{"name":"value","type":"uint224","internalType":"uint224"},{"name":"timestamp","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"getFeeTokens","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"type":"function","name":"getPremiumMultiplierWeiPerEth","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"premiumMultiplierWeiPerEth","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"getStaticConfig","inputs":[],"outputs":[{"name":"","type":"tuple","internalType":"struct FeeQuoter.StaticConfig","components":[{"name":"maxFeeJuelsPerMsg","type":"uint96","internalType":"uint96"},{"name":"linkToken","type":"address","internalType":"address"},{"name":"tokenPriceStalenessThreshold","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"getTokenAndGasPrices","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"destChainSelector","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"tokenPrice","type":"uint224","internalType":"uint224"},{"name":"gasPriceValue","type":"uint224","internalType":"uint224"}],"stateMutability":"view"},{"type":"function","name":"getTokenPrice","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","internalType":"struct Internal.TimestampedPackedUint224","components":[{"name":"value","type":"uint224","internalType":"uint224"},{"name":"timestamp","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"getTokenPriceFeedConfig","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","internalType":"struct FeeQuoter.TokenPriceFeedConfig","components":[{"name":"dataFeedAddress","type":"address","internalType":"address"},{"name":"tokenDecimals","type":"uint8","internalType":"uint8"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}],"stateMutability":"view"},{"type":"function","name":"getTokenPrices","inputs":[{"name":"tokens","type":"address[]","internalType":"address[]"}],"outputs":[{"name":"","type":"tuple[]","internalType":"struct Internal.TimestampedPackedUint224[]","components":[{"name":"value","type":"uint224","internalType":"uint224"},{"name":"timestamp","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"getTokenTransferFeeConfig","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"tokenTransferFeeConfig","type":"tuple","internalType":"struct FeeQuoter.TokenTransferFeeConfig","components":[{"name":"minFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"maxFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"deciBps","type":"uint16","internalType":"uint16"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destBytesOverhead","type":"uint32","internalType":"uint32"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}],"stateMutability":"view"},{"type":"function","name":"getValidatedFee","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"message","type":"tuple","internalType":"struct Client.EVM2AnyMessage","components":[{"name":"receiver","type":"bytes","internalType":"bytes"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"tokenAmounts","type":"tuple[]","internalType":"struct Client.EVMTokenAmount[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"feeToken","type":"address","internalType":"address"},{"name":"extraArgs","type":"bytes","internalType":"bytes"}]}],"outputs":[{"name":"feeTokenAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getValidatedTokenPrice","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint224","internalType":"uint224"}],"stateMutability":"view"},{"type":"function","name":"onReport","inputs":[{"name":"metadata","type":"bytes","internalType":"bytes"},{"name":"report","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"processMessageArgs","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"feeToken","type":"address","internalType":"address"},{"name":"feeTokenAmount","type":"uint256","internalType":"uint256"},{"name":"extraArgs","type":"bytes","internalType":"bytes"},{"name":"messageReceiver","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"msgFeeJuels","type":"uint256","internalType":"uint256"},{"name":"isOutOfOrderExecution","type":"bool","internalType":"bool"},{"name":"convertedExtraArgs","type":"bytes","internalType":"bytes"},{"name":"tokenReceiver","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"processPoolReturnData","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"onRampTokenTransfers","type":"tuple[]","internalType":"struct Internal.EVM2AnyTokenTransfer[]","components":[{"name":"sourcePoolAddress","type":"address","internalType":"address"},{"name":"destTokenAddress","type":"bytes","internalType":"bytes"},{"name":"extraData","type":"bytes","internalType":"bytes"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"destExecData","type":"bytes","internalType":"bytes"}]},{"name":"sourceTokenAmounts","type":"tuple[]","internalType":"struct Client.EVMTokenAmount[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"destExecDataPerToken","type":"bytes[]","internalType":"bytes[]"}],"stateMutability":"view"},{"type":"function","name":"setReportPermissions","inputs":[{"name":"permissions","type":"tuple[]","internalType":"struct KeystoneFeedsPermissionHandler.Permission[]","components":[{"name":"forwarder","type":"address","internalType":"address"},{"name":"workflowName","type":"bytes10","internalType":"bytes10"},{"name":"reportName","type":"bytes2","internalType":"bytes2"},{"name":"workflowOwner","type":"address","internalType":"address"},{"name":"isAllowed","type":"bool","internalType":"bool"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"type":"function","name":"transferOwnership","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"typeAndVersion","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"updatePrices","inputs":[{"name":"priceUpdates","type":"tuple","internalType":"struct Internal.PriceUpdates","components":[{"name":"tokenPriceUpdates","type":"tuple[]","internalType":"struct Internal.TokenPriceUpdate[]","components":[{"name":"sourceToken","type":"address","internalType":"address"},{"name":"usdPerToken","type":"uint224","internalType":"uint224"}]},{"name":"gasPriceUpdates","type":"tuple[]","internalType":"struct Internal.GasPriceUpdate[]","components":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"usdPerUnitGas","type":"uint224","internalType":"uint224"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateTokenPriceFeeds","inputs":[{"name":"tokenPriceFeedUpdates","type":"tuple[]","internalType":"struct FeeQuoter.TokenPriceFeedUpdate[]","components":[{"name":"sourceToken","type":"address","internalType":"address"},{"name":"feedConfig","type":"tuple","internalType":"struct FeeQuoter.TokenPriceFeedConfig","components":[{"name":"dataFeedAddress","type":"address","internalType":"address"},{"name":"tokenDecimals","type":"uint8","internalType":"uint8"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"AuthorizedCallerAdded","inputs":[{"name":"caller","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"AuthorizedCallerRemoved","inputs":[{"name":"caller","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"DestChainAdded","inputs":[{"name":"destChainSelector","type":"uint64","indexed":true,"internalType":"uint64"},{"name":"destChainConfig","type":"tuple","indexed":false,"internalType":"struct FeeQuoter.DestChainConfig","components":[{"name":"isEnabled","type":"bool","internalType":"bool"},{"name":"maxNumberOfTokensPerMsg","type":"uint16","internalType":"uint16"},{"name":"maxDataBytes","type":"uint32","internalType":"uint32"},{"name":"maxPerMsgGasLimit","type":"uint32","internalType":"uint32"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destGasPerPayloadByteBase","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteHigh","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteThreshold","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityOverheadGas","type":"uint32","internalType":"uint32"},{"name":"destGasPerDataAvailabilityByte","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityMultiplierBps","type":"uint16","internalType":"uint16"},{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"},{"name":"enforceOutOfOrder","type":"bool","internalType":"bool"},{"name":"defaultTokenFeeUSDCents","type":"uint16","internalType":"uint16"},{"name":"defaultTokenDestGasOverhead","type":"uint32","internalType":"uint32"},{"name":"defaultTxGasLimit","type":"uint32","internalType":"uint32"},{"name":"gasMultiplierWeiPerEth","type":"uint64","internalType":"uint64"},{"name":"gasPriceStalenessThreshold","type":"uint32","internalType":"uint32"},{"name":"networkFeeUSDCents","type":"uint32","internalType":"uint32"}]}],"anonymous":false},{"type":"event","name":"DestChainConfigUpdated","inputs":[{"name":"destChainSelector","type":"uint64","indexed":true,"internalType":"uint64"},{"name":"destChainConfig","type":"tuple","indexed":false,"internalType":"struct FeeQuoter.DestChainConfig","components":[{"name":"isEnabled","type":"bool","internalType":"bool"},{"name":"maxNumberOfTokensPerMsg","type":"uint16","internalType":"uint16"},{"name":"maxDataBytes","type":"uint32","internalType":"uint32"},{"name":"maxPerMsgGasLimit","type":"uint32","internalType":"uint32"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destGasPerPayloadByteBase","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteHigh","type":"uint8","internalType":"uint8"},{"name":"destGasPerPayloadByteThreshold","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityOverheadGas","type":"uint32","internalType":"uint32"},{"name":"destGasPerDataAvailabilityByte","type":"uint16","internalType":"uint16"},{"name":"destDataAvailabilityMultiplierBps","type":"uint16","internalType":"uint16"},{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"},{"name":"enforceOutOfOrder","type":"bool","internalType":"bool"},{"name":"defaultTokenFeeUSDCents","type":"uint16","internalType":"uint16"},{"name":"defaultTokenDestGasOverhead","type":"uint32","internalType":"uint32"},{"name":"defaultTxGasLimit","type":"uint32","internalType":"uint32"},{"name":"gasMultiplierWeiPerEth","type":"uint64","internalType":"uint64"},{"name":"gasPriceStalenessThreshold","type":"uint32","internalType":"uint32"},{"name":"networkFeeUSDCents","type":"uint32","internalType":"uint32"}]}],"anonymous":false},{"type":"event","name":"FeeTokenAdded","inputs":[{"name":"feeToken","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"FeeTokenRemoved","inputs":[{"name":"feeToken","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferRequested","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"PremiumMultiplierWeiPerEthUpdated","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"premiumMultiplierWeiPerEth","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"PriceFeedPerTokenUpdated","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"priceFeedConfig","type":"tuple","indexed":false,"internalType":"struct FeeQuoter.TokenPriceFeedConfig","components":[{"name":"dataFeedAddress","type":"address","internalType":"address"},{"name":"tokenDecimals","type":"uint8","internalType":"uint8"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}],"anonymous":false},{"type":"event","name":"ReportPermissionSet","inputs":[{"name":"reportId","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"permission","type":"tuple","indexed":false,"internalType":"struct KeystoneFeedsPermissionHandler.Permission","components":[{"name":"forwarder","type":"address","internalType":"address"},{"name":"workflowName","type":"bytes10","internalType":"bytes10"},{"name":"reportName","type":"bytes2","internalType":"bytes2"},{"name":"workflowOwner","type":"address","internalType":"address"},{"name":"isAllowed","type":"bool","internalType":"bool"}]}],"anonymous":false},{"type":"event","name":"TokenTransferFeeConfigDeleted","inputs":[{"name":"destChainSelector","type":"uint64","indexed":true,"internalType":"uint64"},{"name":"token","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TokenTransferFeeConfigUpdated","inputs":[{"name":"destChainSelector","type":"uint64","indexed":true,"internalType":"uint64"},{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"tokenTransferFeeConfig","type":"tuple","indexed":false,"internalType":"struct FeeQuoter.TokenTransferFeeConfig","components":[{"name":"minFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"maxFeeUSDCents","type":"uint32","internalType":"uint32"},{"name":"deciBps","type":"uint16","internalType":"uint16"},{"name":"destGasOverhead","type":"uint32","internalType":"uint32"},{"name":"destBytesOverhead","type":"uint32","internalType":"uint32"},{"name":"isEnabled","type":"bool","internalType":"bool"}]}],"anonymous":false},{"type":"event","name":"UsdPerTokenUpdated","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"timestamp","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"UsdPerUnitGasUpdated","inputs":[{"name":"destChain","type":"uint64","indexed":true,"internalType":"uint64"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"timestamp","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"CannotTransferToSelf","inputs":[]},{"type":"error","name":"DataFeedValueOutOfUint224Range","inputs":[]},{"type":"error","name":"DestinationChainNotEnabled","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"}]},{"type":"error","name":"ExtraArgOutOfOrderExecutionMustBeTrue","inputs":[]},{"type":"error","name":"FeeTokenNotSupported","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"Invalid32ByteAddress","inputs":[{"name":"encodedAddress","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"InvalidChainFamilySelector","inputs":[{"name":"chainFamilySelector","type":"bytes4","internalType":"bytes4"}]},{"type":"error","name":"InvalidDestBytesOverhead","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"destBytesOverhead","type":"uint32","internalType":"uint32"}]},{"type":"error","name":"InvalidDestChainConfig","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"}]},{"type":"error","name":"InvalidEVMAddress","inputs":[{"name":"encodedAddress","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"InvalidExtraArgsData","inputs":[]},{"type":"error","name":"InvalidExtraArgsTag","inputs":[]},{"type":"error","name":"InvalidFeeRange","inputs":[{"name":"minFeeUSDCents","type":"uint256","internalType":"uint256"},{"name":"maxFeeUSDCents","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSVMExtraArgsWritableBitmap","inputs":[{"name":"accountIsWritableBitmap","type":"uint64","internalType":"uint64"},{"name":"numAccounts","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidStaticConfig","inputs":[]},{"type":"error","name":"InvalidTokenReceiver","inputs":[]},{"type":"error","name":"MessageComputeUnitLimitTooHigh","inputs":[]},{"type":"error","name":"MessageFeeTooHigh","inputs":[{"name":"msgFeeJuels","type":"uint256","internalType":"uint256"},{"name":"maxFeeJuelsPerMsg","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"MessageGasLimitTooHigh","inputs":[]},{"type":"error","name":"MessageTooLarge","inputs":[{"name":"maxSize","type":"uint256","internalType":"uint256"},{"name":"actualSize","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"MustBeProposedOwner","inputs":[]},{"type":"error","name":"OnlyCallableByOwner","inputs":[]},{"type":"error","name":"OwnerCannotBeZero","inputs":[]},{"type":"error","name":"ReportForwarderUnauthorized","inputs":[{"name":"forwarder","type":"address","internalType":"address"},{"name":"workflowOwner","type":"address","internalType":"address"},{"name":"workflowName","type":"bytes10","internalType":"bytes10"},{"name":"reportName","type":"bytes2","internalType":"bytes2"}]},{"type":"error","name":"SourceTokenDataTooLarge","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"StaleGasPrice","inputs":[{"name":"destChainSelector","type":"uint64","internalType":"uint64"},{"name":"threshold","type":"uint256","internalType":"uint256"},{"name":"timePassed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"TokenNotSupported","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"TooManySVMExtraArgsAccounts","inputs":[{"name":"numAccounts","type":"uint256","internalType":"uint256"},{"name":"maxAccounts","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"UnauthorizedCaller","inputs":[{"name":"caller","type":"address","internalType":"address"}]},{"type":"error","name":"UnsupportedNumberOfTokens","inputs":[{"name":"numberOfTokens","type":"uint256","internalType":"uint256"},{"name":"maxNumberOfTokensPerMsg","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ZeroAddressNotAllowed","inputs":[]}]`
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran make operations-fast to update renamed field PremiumMultiplierWeiPerEthArgs → FeeTokenArgs

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should not change. This is strange. It's based on a static wrapper that isn't changed in this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was changed in a previous PR and wasn't updated. Will double check again.

@asoliman92 asoliman92 changed the title rmn curse admins RMNRemote: curse admin management + blessing removal [CCIP-10871] Apr 20, 2026
Comment thread chains/evm/contracts/rmn/RMNRemote.sol Outdated
Comment thread chains/evm/contracts/rmn/RMNRemote.sol Outdated
Comment thread chains/evm/contracts/rmn/RMNRemote.sol Outdated
Comment thread chains/evm/contracts/rmn/RMNRemote.sol Outdated
Comment thread chains/evm/contracts/rmn/RMNRemote.sol Outdated
Comment thread chains/evm/contracts/rmn/RMNRemote.sol
}

function test_RevertWhen_curse_calledByNonOwner() public {
vm.expectRevert(abi.encodeWithSelector(RMNRemote.OnlyOwnerOrCurseAdmin.selector, STRANGER));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: nothing should be between the expect and the call, pranks should be done before the expect

}
}

contract RMNRemote_curseAdmin is RMNRemoteSetup {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only allow a single contract per file. See the style guide

s_rmnRemote.applyCurseAdminUpdates(new address[](0), adds);
}

function test_curse_byCurseAdmin_Success() public {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we no longer use success suffix for the base case, maybe the old tests for RMN did that since they have not been updated in a long time, but let's follow the new style

assertTrue(s_rmnRemote.isCursed(CURSE_SUBJ_2));
}

function test_applyCurseAdminUpdates_addsAndRemoves() public {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have one file per tested function. Should be semi-solved if you use allowedCallers instead of custom code as that will reduce the to-be-tested functions a lot.


import {RMNRemoteSetup} from "./RMNRemoteSetup.t.sol";

contract RMNRemote_constructor is RMNRemoteSetup {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other tests already use the constructor. Don't see a need for us to keep this one.

@asoliman92 asoliman92 changed the title RMNRemote: curse admin management + blessing removal [CCIP-10871] RMNRemote: curse admin management + legacy rmn removal [CCIP-10871] Apr 22, 2026
@asoliman92 asoliman92 marked this pull request as ready for review April 22, 2026 13:44
Copilot AI review requested due to automatic review settings April 22, 2026 13:44
@asoliman92 asoliman92 requested review from a team as code owners April 22, 2026 13:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR migrates the EVM “RMNRemote” usage to a new “RMN” contract, removes legacy RMNRemote artifacts/APIs, and updates downstream integrations (Solidity tests + Go bindings) to use the new RMN naming and interface.

Changes:

  • Replaced RMNRemote references with RMN across scripts, Solidity contracts, and tests (OnRamp/OffRamp/Router/pools/verifiers).
  • Removed the legacy RMNRemote Solidity contract + IRMNRemote interface, and introduced a new RMN contract focused on curse management with authorized callers.
  • Regenerated Go bindings and wrapper dependency metadata for the new RMN contract.

Reviewed changes

Copilot reviewed 93 out of 99 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
chains/evm/scripts/compile_all Switch compilation target from RMNRemote to RMN.
chains/evm/gobindings/go_generate.go Update go:generate wrapper target to RMN.
chains/evm/gobindings/generation/generated-wrapper-dependency-versions-do-not-edit.txt Add RMN wrapper inputs; update dependency hashes.
chains/evm/gobindings/generated/latest/rmn_remote/rmn_remote.go Remove generated Go bindings for RMNRemote.
chains/evm/gobindings/generated/latest/rmn/rmn.go Add generated Go bindings for RMN.
chains/evm/contracts/test/rmn/RMNRemote/RMNSetup.t.sol Add new RMN test setup using RMN contract.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemoteSetup.t.sol Remove RMNRemote-specific test setup and helpers.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.verifywithConfigSet.t.sol Remove RMNRemote verify tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.verifywithConfigNotSet.t.sol Remove RMNRemote verify tests for missing config.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.uncurse.t.sol Remove RMNRemote uncurse tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.setConfig.t.sol Remove RMNRemote config tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.isBlessed.t.sol Remove legacy isBlessed passthrough tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.globalCurses.t.sol Remove RMNRemote global curse tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.curse.t.sol Remove RMNRemote curse tests.
chains/evm/contracts/test/rmn/RMNRemote/RMNRemote.constructor.t.sol Remove RMNRemote constructor test.
chains/evm/contracts/test/rmn/RMNRemote/RMN.uncurse.t.sol Add RMN uncurse tests incl. curse-admin behavior.
chains/evm/contracts/test/rmn/RMNRemote/RMN.globalCurses.t.sol Add RMN global curse tests.
chains/evm/contracts/test/rmn/RMNRemote/RMN.curse.t.sol Add RMN curse tests incl. authorized caller behavior.
chains/evm/contracts/test/rmn/RMNProxy/RMNProxy.isCursed.t.sol Update proxy tests to use RMN instead of RMNRemote.
chains/evm/contracts/test/pools/USDC/USDCSetup.t.sol Use s_mockRMN in Router setup.
chains/evm/contracts/test/pools/USDC/SiloedUSDCTokenPool/SiloedUSDCTokenPoolSetup.sol Pass RMN mock where RMNRemote mock was used.
chains/evm/contracts/test/pools/USDC/CCTPTokenPool/CCTPThroughCCVTokenPoolSetup.t.sol Pass RMN mock into pool setup.
chains/evm/contracts/test/pools/USDC/CCTPTokenPool/CCTPThroughCCVTokenPool.constructor.t.sol Update constructor test wiring to RMN mock.
chains/evm/contracts/test/pools/TokenPool/TokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/TokenPool/TokenPool.validateReleaseOrMint.t.sol Update mockCall target to RMN mock.
chains/evm/contracts/test/pools/TokenPool/TokenPool.constructor.t.sol Update assertions/constructors to use RMN mock.
chains/evm/contracts/test/pools/TokenPool/TokenPool.calculateLocalAmount.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.getAllLockBoxConfigs.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.constructor.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.configureLockBoxes.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPool.lockOrBurn.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPool.getRequiredCCVs.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPool._getTokenDecimals.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.releaseOrMint.t.sol Update mockCall to RMN mock.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.lockOrBurn.t.sol Update mockCall to RMN mock.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.constructor.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolTokenSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.sendReceive.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.releaseOrMint.t.sol Update mockCall to RMN mock.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.lockOrBurn.t.sol Update mockCall to RMN mock.
chains/evm/contracts/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol Replace RMNRemote mock with RMN mock and update assertions/mocks.
chains/evm/contracts/test/pools/BurnToAddressMintTokenPool/BurnToAddressMintTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/BurnMintTokenPool/BurnMintTokenPool.typeAndVersion.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol Replace RMNRemote mock with RMN mock and update mockCall.
chains/evm/contracts/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol Replace RMNRemote mock with RMN mock and update mockCall/assertions.
chains/evm/contracts/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPool.lockOrBurn.t.sol Replace RMNRemote mock with RMN mock and update mockCall/assertions.
chains/evm/contracts/test/pools/AdvancedPoolHooks/AdvancedPoolHooksSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/pools/AdvancedPoolHooks/AdvancedPoolHooks.applyAllowListUpdates.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRampSetup.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.parseExtraArgsWithDefaults.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.mergeCCVsLists.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.lockOrBurnSingleToken.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.getCCVsForPool.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.constructor.t.sol Replace IRMNRemote import/usage with IRMN.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp._validateDestChainAddress.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp._getExecutionFee.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/offRamp/OffRamp/OffRampSetup.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.releaseOrMintSingleToken.t.sol Replace RMNRemote mock with RMN mock in pool and OffRamp.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.getStaticConfig.t.sol Update static config assertions to rmn field.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.getBalanceOfReceiver.t.sol Update static config field to rmn and RMN mock.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.execute.t.sol Update mockCall target to RMN mock.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.constructor.t.sol Replace IRMNRemote import/usage with IRMN and update assertions.
chains/evm/contracts/test/e2e/e2e.t.sol Replace RMNRemote mock with RMN mock wiring in verifiers + OffRamp.
chains/evm/contracts/test/e2e/e2e.lombard.t.sol Replace RMNRemote mock with RMN mock wiring in verifiers/pools/OffRamp.
chains/evm/contracts/test/e2e/e2e.feeWithdraw.t.sol Replace RMNRemote mock with RMN mock wiring in pools/verifier/OffRamp.
chains/evm/contracts/test/e2e/e2e.factoryDeployedPool.t.sol Replace RMNRemote mock with RMN mock in factory wiring.
chains/evm/contracts/test/e2e/e2e.cctp.t.sol Replace RMNRemote mock with RMN mock in setup/deploy wiring.
chains/evm/contracts/test/ccvs/components/BaseVerifier/BaseVerifierSetup.t.sol Pass RMN mock to BaseVerifier helper.
chains/evm/contracts/test/ccvs/components/BaseVerifier/BaseVerifier.constructor.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/ccvs/LombardVerifier/LombardVerifierSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/ccvs/LombardVerifier/LombardVerifier.constructor.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/ccvs/CommitteeVerifier/CommitteeVerifierSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/ccvs/CommitteeVerifier/CommitteeVerifier.constructor.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/ccvs/CCTPVerifier/CCTPVerifierSetup.t.sol Update BaseVerifierArgs to use RMN mock.
chains/evm/contracts/test/ccvs/CCTPVerifier/CCTPVerifier.constructor.t.sol Update BaseVerifierArgs to use RMN mock.
chains/evm/contracts/test/attacks/OnRamp/OnRampTokenPoolReentrancy.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/TokenSetup.t.sol Replace RMNRemote mock with RMN mock.
chains/evm/contracts/test/Router/RouterSetup.t.sol Update OnRamp static config to use rmn and RMN mock.
chains/evm/contracts/test/Router/Router.routeMessage.t.sol Update mockCall target to RMN mock.
chains/evm/contracts/test/Router/Router.getArmProxy.t.sol Update expected ARM proxy to RMN mock.
chains/evm/contracts/test/Router/Router.ccipSend.t.sol Update mockCall target to RMN mock.
chains/evm/contracts/test/BaseTest.t.sol Replace IRMNRemote mock with IRMN mock and update router wiring.
chains/evm/contracts/rmn/RMNRemote.sol Remove legacy RMNRemote contract implementation.
chains/evm/contracts/rmn/RMN.sol Add new RMN contract with curse admin management.
chains/evm/contracts/onRamp/OnRamp.sol Replace IRMNRemote references with IRMN and rename static config field.
chains/evm/contracts/offRamp/OffRamp.sol Replace IRMNRemote references with IRMN and rename static config field.
chains/evm/contracts/interfaces/IRMNRemote.sol Remove legacy IRMNRemote interface.
chains/evm/contracts/interfaces/IRMN.sol Remove legacy isBlessed API; keep curse-related APIs.
chains/evm/contracts/ccvs/components/BaseVerifier.sol Replace IRMNRemote reference with IRMN.
Comments suppressed due to low confidence (2)

chains/evm/gobindings/generation/generated-wrapper-dependency-versions-do-not-edit.txt:1

  • The wrapper-dependency manifest still lists rmn_remote inputs even though chains/evm/contracts/rmn/RMNRemote.sol and the generated Go binding generated/latest/rmn_remote/rmn_remote.go were removed in this PR. This is likely to break wrapper generation/builds by referencing missing ABI/BIN paths. Remove the rmn_remote entry (and any corresponding solc artifacts) if RMNRemote is fully deprecated, or keep/regenerate RMNRemote artifacts consistently if it must remain supported.
    chains/evm/contracts/test/rmn/RMNRemote/RMNSetup.t.sol:1
  • The new setup contract is named RMNRemoteSetup but it instantiates and exposes RMN (s_rmn). Renaming the setup contract (and the derived test contract names/files under this folder) to RMNSetup/RMN_* would make it clearer that these tests cover RMN rather than the removed RMNRemote.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread chains/evm/contracts/rmn/RMN.sol
Comment thread chains/evm/contracts/onRamp/OnRamp.sol Outdated
struct StaticConfig {
uint64 chainSelector; // ─────────╮ Local chain selector.
IRMNRemote rmnRemote; // │ RMN remote address.
IRMN rmn; // │ RMN remote address.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After switching the type from IRMNRemote to IRMN and renaming the struct field to rmn, the internal immutable is still named i_rmnRemote. Renaming it to something like i_rmn (and updating the related comment and getStaticConfig() return field assignment) would reduce confusion and prevent future mis-wirings where a 'remote verifier' is assumed to exist.

Suggested change
IRMN rmn; // │ RMN remote address.
IRMN rmn; // │ RMN address.

Copilot uses AI. Check for mistakes.
Comment thread chains/evm/contracts/onRamp/OnRamp.sol
uint64 localChainSelector; // ──╮ Local chainSelector
uint16 gasForCallExactCheck; // │ Gas for call exact check
IRMNRemote rmnRemote; // ───────╯ RMN Verification Contract
IRMN rmn; // ───────╯ RMN Verification Contract
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to OnRamp, the type has been changed to IRMN and the config field is now rmn, but the immutable is still named i_rmnRemote and comments still refer to a 'verification contract'. Rename the variable and align the comment to reflect the new responsibilities (curse-signal vs verification) to avoid inaccurate mental models for maintainers.

Suggested change
IRMN rmn; // ───────╯ RMN Verification Contract
IRMN rmn; // ───────╯ RMN contract used for curse checks

Copilot uses AI. Check for mistakes.
Comment thread chains/evm/contracts/offRamp/OffRamp.sol
s_mockRMN = IRMN(makeAddr("MOCK RMN REMOTE"));
vm.etch(address(s_mockRMN), bytes("fake bytecode"));
vm.mockCall(address(s_mockRMN), abi.encodeWithSignature("isCursed()"), abi.encode(false));
vm.mockCall(address(s_mockRMN), abi.encodeWithSignature("isCursed(bytes16)"), abi.encode(false)); // no curses by defaule
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct typo in comment: 'defaule' → 'default'.

Suggested change
vm.mockCall(address(s_mockRMN), abi.encodeWithSignature("isCursed(bytes16)"), abi.encode(false)); // no curses by defaule
vm.mockCall(address(s_mockRMN), abi.encodeWithSignature("isCursed(bytes16)"), abi.encode(false)); // no curses by default

Copilot uses AI. Check for mistakes.
uint64 localChainSelector; // ──╮ Local chainSelector
uint16 gasForCallExactCheck; // │ Gas for call exact check
IRMNRemote rmnRemote; // ───────╯ RMN Verification Contract
IRMN rmn; // ───────╯ RMN Verification Contract
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot change any of these contracts, as that would change the bytecode. You can only change RMN and tests, no other bytecode should change.

Note that renaming the contract to IRMN does not change bytecode in a contract like this, but this variable rename does.

function isCursed() external view returns (bool);

/// @notice Iff there is an active global curse, or an active curse for `subject`, this function returns true.
/// @notice If there is an active global curse, or an active curse for `subject`, this function returns true.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iff here means if and only if, it's not a typo

Comment thread chains/evm/contracts/rmn/RMN.sol Outdated
// ================================================================

/// @notice Curse a single subject.
/// @param subject the subject to curse.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The instead of the

Comment thread chains/evm/contracts/rmn/RMN.sol Outdated
function curse(
bytes16[] memory subjects
) public {
if (msg.sender != owner()) _validateCaller();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we make this

if (msg.sender != owner()) {
    _validateCaller();
}

and add a comment explaining what it does as it's quite unusual code

@asoliman92 asoliman92 force-pushed the asoliman/rmn-curse-admins branch from 4b9058b to f3d042d Compare April 22, 2026 14:36
@github-actions
Copy link
Copy Markdown

Metric asoliman/rmn-curse-admins main
Coverage 70.1% 69.9%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants